package cn.com.oceansoft.business.mobile.danger.util;

import cn.com.oceansoft.business.mobile.danger.entity.AccessToken;
import cn.com.oceansoft.business.mobile.danger.entity.WXOauth2Token;
import cn.com.oceansoft.nos.cache.redis.CacheBaseService;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class WeixinUtil {
	//这里使用的是固定的一个通过认证的服务号的appid和secret，目的是让订阅号也能通过网页授权
	public static String APPID="wxe8dc58e12b05f6a7";
	public static String SECRET="1df11da8734cf02dbb79989f27021d7c";

	//这里使用的是固定的一个通过认证的服务号的appid和secret，目的是从获取省厅的access_token
	public static String STAPPID="10000149";
	public static String STAPPKEY="083b80307ddb93da0069391be36802e5";
	/**
	 * 获取access_token接口(通用接口)
	 */
	public static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	public static String GETTICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";

	/**
	 * 获取省厅的access_token接口（2个小时过期）
	 */
	public static String ST_ACCESS_TOKEN_URL="http://www.api.jsga.gov.cn/api/api/get_access_token?app_id=STAPPID&app_key=STAPPKEY";

	/**
	 * 	省厅公众号授权接口
	 */
	public static String ST_GET_STOPENID_URL="http://www.api.jsga.gov.cn/api/auth?open_id=openid&app_id=appid&return_url=returnUrl&access_token=sttoken";
	/**
	 * 省厅回跳地址
	 */
	public static String return_url="http://wjw.szgaj.cn/szgawx/oauth/oauth3";
	/**
	 * 自定义菜单接口(通用接口)
	 */
	public static String CREATEMENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
	public static String GET_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
	public static String DEL_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";

	/**
	 * 获取用户基本信息(认证服务号的高级接口)
	 */
	public static String WX_USER_INFO="https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
	/**
	 * 获取授权用户信息(认证服务号的高级接口)
	 */
	public static String WX_SNSUSER_INFO="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";


	/**
	* 刷新oauth2的access_token接口地址(认证服务号的高级接口)
	*/
	public static String OAUTH_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	/**
	 * oauth2授权接口,不显示授权页面(认证服务号的高级接口)
	 */
	public static String BASE_URL="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=http%3A%2F%2F221.224.33.76%2Foswechat%2FoauthServlet%2Foauth.do&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
	/**
	 * oauth2授权接口,显示授权页面(认证服务号的高级接口)
	 */
	public static String USERINFO_URL="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=http%3A%2F%2F221.224.33.76%2Foswechat%2FoauthServlet%2Foauth.do&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";

	/**
	 * 认证用户登陆
	 */
	public static String USERAUTH_URL="api/Users/IsRegUser";

	/**
	 * 获取用户增减数据
	 */
	public static String GETUSERSUMMARY="https://api.weixin.qq.com/datacube/getusersummary?access_token=ACCESS_TOKEN";
	
	/**
	 * 获取累计用户数据
	 */
	public static String GETUSERCUMULATE="https://api.weixin.qq.com/datacube/getusercumulate?access_token=ACCESS_TOKEN";

	/**
	 * 查询统计
	 */
	public static String SEARCHCOUNT_URL="api/SearchCount/SearchCount";


    public static String GETUSERLIST = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";

    /**
	 * 发起https请求并获取结果
	 *
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpsRequest(String requestUrl,
										  String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);

			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))// get方式为获取token
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.flush();
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			jsonObject = JSONObject.parseObject(buffer.toString());
		} catch (ConnectException ce) {
			ce.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return jsonObject;
	}


	/**
	 * 获取access_token
	 *
	 * @param appid
	 *            凭证
	 * @param appsecret
	 *            密钥
	 * @return
	 */
	public static AccessToken getAccessToken(String appid, String appsecret) {
		AccessToken accessToken = null;

		String requestUrl = ACCESS_TOKEN_URL.replace("APPID", appid).replace(
				"APPSECRET", appsecret);
		JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				accessToken = new AccessToken();
				accessToken.setAccess_token(jsonObject.getString("access_token"));
				//accessToken.setExpires(jsonObject.getInt("expires_in"));
			} catch (Exception e) {
				accessToken = null;
				System.err.println("获取accessToken失败");
				e.printStackTrace();
			}
		}
		return accessToken;
	}



	/***
	 * 获取jsapi_ticket
	 * @param accessToken
	 * @return
     */
	public static String getJsapiTicket(String accessToken){
		String requestUrl = GETTICKET_URL.replace("ACCESS_TOKEN", accessToken);
		JSONObject json = httpsRequest(requestUrl, "GET", null);
		return (String) json.get("ticket");
	}



	public static String getAccessToken() {
        String access_token = "";
        String cachekey = "CMCX_ACCESSTOKEN";
		System.out.println("##############################"+cachekey);
		System.out.println("============================"+cachekey);
		access_token = CacheBaseService.getInstance().get(cachekey);
		System.out.println("============================"+access_token);
        return access_token;
    }

    /**
     * 获取关注用户的列表List第一位是next_openid
     *
     * @param accessToken
     * @param nextOpenid
     * @return
     */
    public static Object[] getUserList(String accessToken, String nextOpenid) {
        List<Object[]> list = new ArrayList<Object[]>();
        String url = GETUSERLIST;
        url = url.replace("ACCESS_TOKEN", accessToken).replace("NEXT_OPENID", nextOpenid);
        JSONObject jo = httpsRequest(url, "GET", null);
        if (null != jo) {
            try {
                //list 第一位是nextOpenid
                String next_openid = jo.getString("next_openid");
                if("".equals(next_openid)){
                    return null;
                }
                JSONObject json = jo.getJSONObject("data");
                Object[] array = json.getJSONArray("openid").toArray();
                for (int i = 0; i < array.length; i++) {
                    list.add(new Object[]{array[i]});
                }
                return new Object[]{next_openid, list};
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println("获取信息失败");
            }
        }
        return null;
    }
	


	public static WXOauth2Token getOauth2AccessToken(String appId, String appSecret, String code){
		String requestUrl=OAUTH_ACCESS_TOKEN_URL;
		requestUrl=requestUrl.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
		JSONObject jo=httpsRequest(requestUrl,"GET",null);
		try {
			if(null!=jo){
				WXOauth2Token wat=new WXOauth2Token();
				System.out.println("=====获取access_token：###"+jo.toString());
				wat.setAccessToken(jo.getString("access_token"));
				System.out.println("access_token"+jo.getString("access_token"));
				//wat.setExpiresIn(jo.getInt("expires_in"));
				wat.setRefreshToken(jo.getString("refresh_token"));
				wat.setOpenId(jo.getString("openid"));
				wat.setScope(jo.getString("scope"));
				return wat;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 刷新access_token
	 * @param appId
	 * @param refreshToken
	 * @return
	 */
	public static WXOauth2Token refreshOauth2AccessToken(String appId, String refreshToken){
		WXOauth2Token wat=new WXOauth2Token();
		String requestUrl="https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
		requestUrl=requestUrl.replace("APPID", appId).replace("REFRESH_TOKEN", refreshToken);
		JSONObject jo=httpsRequest(requestUrl, "GET", null);
		if(null!=jo){
			wat.setAccessToken(jo.getString("access_token"));
			//wat.setExpiresIn(jo.getInt("expires_in"));
			wat.setRefreshToken(jo.getString("refresh_token"));
			wat.setOpenId(jo.getString("openid"));
			wat.setScope(jo.getString("scope"));
		}
		return wat;
	}

	public static<T> Object JSONToObj(String jsonStr,Class<T> obj) {
		T t = null;
		try {
			ObjectMapper objectMapper = new ObjectMapper();
			t = objectMapper.readValue(jsonStr,
					obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return t;
	}


	/**
	 *过滤EMOJI表情
	 */
	public static String filterEmoji(String source) {
		if(source != null)
		{
			Pattern emoji = Pattern.compile ("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",Pattern.UNICODE_CASE | Pattern . CASE_INSENSITIVE ) ;
			Matcher emojiMatcher = emoji.matcher(source);
			if ( emojiMatcher.find())
			{
				source = emojiMatcher.replaceAll("*");
				return source ;
			}
			return source;
		}
		return source;
	}

}
